#include "chip.inc"
#INCLUDE "ISR.INC"
#include "config.inc"
#include "VARS.INC"
#include "circ_buffer.inc"
#include "inits.inc"

;TESTED TO 125KHZ

	ORG 0x0000
	GOTO 	INIT
	
	ORG 0x0008 ;HIGH PRIORITY INTERRUPT
	GOTO	HIGH_PRIORITY_INTERRUPT
	
	ORG 0x0018 ;LOW PRIORITY INTERRUPT
	GOTO 	LOW_PRIORITY_INTERRUPT
	
	ORG 0x0038	
INIT: 
	CALL 	INITS
MAINLOOP:
	CALL 	HANDLE_DATA		;3 - 23	
	CALL 	HANDLE_ACK_NACK	;5 - 25
	CALL 	HANDLE_TX		;3 - 24 - 27
	GOTO 	MAINLOOP
	
;;;;;;;;;;;;;;;;;;HANDLE TX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HANDLE_TX	;3 to (24 to 27 most common when active)
	BTFSS	PIR1,TXIF,A		;CHECK TO SEE IF THE BUFFER IS FREE
	RETURN
	
	;;BUFFER IS FREE, FILL IT IF WE HAVE DATA
	CALL 	Buffer_Peek_Action	;9
	ADDWF	PCL,F,A	;
	RETURN			 		;0 - IDLE
	BRA		TX_START_BIT	;4 - START_BIT
	BRA		TX_STOP_BIT		;8 - STOP_BIT
	BRA		TX_CHAR_HEAD	;12 - CHAR_HEAR
	BRA		TX_CHAR_DATA	;16 - CHAR_DATA
	BRA		TX_ACK_BIT		;20 - ACK
	BRA		TX_NACK_BIT		;24 - NACK
	
TX_START_BIT:
	MOVLW	CHAR_R
	MOVWF	TXREG,A
	CALL	Buffer_Drop
	RETURN
	
TX_STOP_BIT:;
	MOVLW	CHAR_P
	MOVWF	TXREG,A
	CALL	Buffer_Drop
	RETURN
	
TX_CHAR_HEAD:;-15
	MOVLW	CHAR_H
	MOVWF	TXREG,A
	MOVLW	UART_TX_CHAR_DATA
	MOVWF	BUFFER_PUSH_ACTION,A
	CALL	Buffer_ReAssign_Next
	RETURN	;27
	
TX_CHAR_DATA:
	CALL	Buffer_Peek_Data
	MOVWF	TXREG,A
	CALL	Buffer_Drop ;3-6
	RETURN
	
TX_ACK_BIT:
	MOVLW	CHAR_A
	MOVWF	TXREG,A
	CALL	Buffer_Drop
	RETURN
	
TX_NACK_BIT:
	MOVLW	CHAR_N
	MOVWF	TXREG,A
	CALL	Buffer_Drop
	RETURN
;;;;;;;;;;;;;;;;;;HANDLE TX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;HANDLE DATA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HANDLE_DATA: ;3 - 24
;	BCF		SSPCON1,SSPOV,A
;	BCF		SSPCON1,WCOL,A
	BTFSS 	SSPSTAT,BF,A
	RETURN
	
	MOVF	SSPBUF,W,A
	BCF		SSPSTAT,BF,A
	MOVWF	BUFFER_PUSH_DATA,A

	MOVLW	UART_TX_CHAR_HEAD
	MOVWF	BUFFER_PUSH_ACTION
	
	BCF INTCON,GIE,A						;DISABLE INTERRUPTS
	CALL	Buffer_Push	;8-13			;AND SEND IT
	BSF INTCON,GIE,A						;RE-ENABLE INTERRUPTS

	CLRF 	CLOCK_HAS_GONE_LOW,A
	BSF		LOOK_FOR_ACK_NACK,1,A
	BCF		SSPCON1,SSPEN,A				;DISABLE DATA
	RETURN
;;;;;;;;;;;;;;;;;;HANDLE DATA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;HANDLE ACK/NACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HANDLE_ACK_NACK ;5 - 25
	MOVF 	LOOK_FOR_ACK_NACK,F,A
	BZ		DONE_HANDLING_ACK_NACK
	
	MOVF	CLOCK_HAS_GONE_LOW,F,A		;WAIT FOR CLOCK TO GO LOW
	BZ		CHECK_FOR_CLOCK_IS_LOW
	
	BTFSS	SPORT,SCLK,A				;AND THEN WAIT FOR CLOCK TO COME BACK UP
	RETURN
	
	MOVLW	UART_TX_ACK
	BTFSC	SPORT,SDAT,A
	MOVLW 	UART_TX_NACK				;SELECT ACK OR NACK
	
	MOVWF	BUFFER_PUSH_ACTION
	BCF INTCON,GIE,A						;DISABLE INTERRUPTS
	CALL	Buffer_Push_Action			;AND SEND IT
	BSF INTCON,GIE,A						;RE-ENABLE INTERRUPTS
	
	CLRF 	LOOK_FOR_ACK_NACK,A			;RESET FLAGS
	CLRF	CHECK_FOR_CLOCK_IS_LOW,A
	
	BSF		SSPCON1,SSPEN,A				;RE-ENABLE DATA

	RETURN
	
CHECK_FOR_CLOCK_IS_LOW:
	BTFSS	SPORT,SCLK,A
	BSF	CLOCK_HAS_GONE_LOW,0,A
	
DONE_HANDLING_ACK_NACK:
	RETURN
;;;;;;;;;;;;;;;;;;HANDLE ACK/NACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

	END